// src/components/AuthExample.js

// 导入 React 核心库，已经存 Component 别名简写
import React, { Component } from 'react';

/*
Redirect 重定向 将导航到新的位置，新位置将覆盖历史堆栈中的当前位置
*/
import {
  Route,
  Link,
  Redirect,
  withRouter,
} from 'react-router-dom';

// 模拟授权.
const fakeAuth = {
  // 是否通过认证.
  isAuthenticated: false,

  /**
   * 认证（登入）
   * @param cb {Function} 回调函数.
   */
  authenticate(cb) {
    this.isAuthenticated = true;
    setTimeout(cb, 100); // 假异步
  },

  /**
   * 登出
   * @param cb {Function} 回调函数.
   */
  signout(cb) {
    // 变更认证状态.
    this.isAuthenticated = false;
    setTimeout(cb, 100);  // 假异步
  },
};

/*
 * 组件包含 两个子组件
 * - AuthButton
 * - PrivateRoute
 */
const AuthExample = () => (
  <div>
    {/* 授权按钮 */}
    <AuthButton />

    <ul>
      <li><Link to="/home">Home Page</Link></li>
      <li><Link to="/public">Public Page</Link></li>
      <li><Link to="/protected">Protected Page</Link></li>
    </ul>

    <Route path="/home" render={() => <div>Home</div>} />
    <Route path="/public" component={Public} />
    <Route path="/login" component={Login} />

    {/* 私有 */}
    <PrivateRoute path="/protected" component={Protected} />
  </div>
);

// 授权按钮 子组件.
const AuthButton = withRouter(({ history }) => {
  // 是否通过授权.
  let { isAuthenticated } = fakeAuth;
  // 登录用户 显示用户信息.
  let welcome = (
    <p>
      欢迎! <button onClick={() => {
        fakeAuth.signout(() => history.push('/'))
      }}>注销</button>
    </p>
  );
  // 未登录用户 提示未登录.
  let notLogin = (
    <p>你没有登录~</p>
  );

  // 返回组件.
  return isAuthenticated ? welcome : notLogin;
});

// 实现私有 子组件.
const PrivateRoute = ({ component: Component, ...rest }) => (
  <Route {...rest} render={
    props => {
      // 是否通过授权.
      let { isAuthenticated } = fakeAuth;
      // 登录用户私有组件.
      let userComponent = <Component {...props} />;
      // 未登录用户重定向.
      let notLogin = (
        <Redirect to={{
          pathname: '/login',
          state: { from: props.location }
        }} />
      );

      // 返回组件.
      return isAuthenticated ? userComponent : notLogin
    }
  } />
);

// 公共组件.
const Public = () => <h3>Public</h3>
// 受保护组件.
const Protected = () => <h3>Protected</h3>

/** 登录类 */
class Login extends Component {
  constructor() {
    super();
    this.state = {
      redirectToReferrer: false  // 重定向到来源.
    };
  }

  // 登录方法.
  login = () => {
    fakeAuth.authenticate(() => {
      this.setState({ redirectToReferrer: true })
    })
  }

  render() {

    // 重定向路径.
    const { from } = this.props.location.state || { from: { pathname: '/' } };
    // 简化 state 属性.
    const { redirectToReferrer } = this.state;

    // 是否重定向到推荐地址.
    return redirectToReferrer ? (
      <Redirect to={ from } />
    ) : (
      <div>
        {/* 登录提示 */}
        <p>必须登录才能查看该页面 {from.pathname}</p>

        {/* 单击登录按钮，进行登录授权，并且激活登录重定向 */}
        <button onClick={this.login} >登录</button>
      </div>
    );
  }
}

export default AuthExample;
